package local.xinshi.netmgr;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.resource.ContentVersionStrategy;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

import local.xinshi.netmgr.pkg.UserSessions;
import local.xinshi.netmgr.pkg.WsHandler;
import local.xinshi.netmgr.pkg.WsInterceptor;

import java.util.EventListener;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@SpringBootApplication
@EnableWebSocket
public class App implements WebSocketConfigurer {
    public static void main(String[] args) {
        SpringApplication.run(App.class, args);
    }

    @Bean
    ServletListenerRegistrationBean<EventListener> setListener(){
        ServletListenerRegistrationBean<EventListener> registrationBean = new ServletListenerRegistrationBean<>();
        registrationBean.setListener(new HttpSessionListener(){
            @Override
            public void sessionDestroyed(HttpSessionEvent se) {
                HttpSession session = se.getSession();
                Object login = session.getAttribute("login");
                if(login == null) return;
                UserSessions.delSession(login.toString(),session);
            }
        });
        return registrationBean;
    }
    @Bean
    WebMvcConfigurer createWebMvcConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addResourceHandlers(ResourceHandlerRegistry registry) {
                registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/")
                        .setCachePeriod(25920000).resourceChain(true).addResolver(
                                new VersionResourceResolver().addVersionStrategy(new ContentVersionStrategy(), "/**"));
            }

            @Override
            public void addInterceptors(InterceptorRegistry registry) {
                registry.addInterceptor(new HandlerInterceptor() {
                    @Override
                    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                            throws Exception {
                        if (request.getSession().getAttribute("login") == null) {
                            response.sendRedirect("/");
                            return false;
                        }
                        return true;
                    }
                }).addPathPatterns("/*").excludePathPatterns("/login", "/").order(1);
                registry.addInterceptor(new HandlerInterceptor() {
                    @Override
                    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                            throws Exception {
                        Object role = request.getSession().getAttribute("role");
                        if (role == null) {
                            response.setStatus(404);
                            return false;
                        }
                        return "管理员".equals(role.toString());
                    }
                }).addPathPatterns("/mgr/*");
            }
        };
    }

    /**
     * @return 执行计划任务的调度器
     */
    @Bean
    public ThreadPoolTaskScheduler createScheduler() {
        return new ThreadPoolTaskScheduler();
    } 

    @Autowired
    WsHandler handler;
    @Autowired
    WsInterceptor interceptor;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(handler, "/state").addInterceptors(interceptor);
    }
}
